<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>可自定义尺寸的2048游戏</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif;
            background: #faf8ef;
            color: #776e65;
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
            padding: 20px;
        }

        .container {
            max-width: 500px;
            width: 100%;
        }

        .header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 20px;
        }

        h1 {
            font-size: 48px;
            font-weight: bold;
            color: #776e65;
        }

        .score-container {
            display: flex;
            gap: 10px;
        }

        .score-box {
            background: #bbada0;
            padding: 10px 20px;
            border-radius: 3px;
            color: white;
            text-align: center;
        }

        .score-label {
            font-size: 13px;
            font-weight: bold;
            text-transform: uppercase;
        }

        .score-value {
            font-size: 25px;
            font-weight: bold;
        }

        .controls {
            margin-bottom: 20px;
            text-align: center;
        }

        .size-input {
            padding: 8px 15px;
            font-size: 16px;
            border: 1px solid #bbada0;
            border-radius: 3px;
            margin-right: 10px;
            width: 80px;
            text-align: center;
        }

        .btn {
            background: #8f7a66;
            color: white;
            border: none;
            padding: 10px 20px;
            border-radius: 3px;
            font-size: 16px;
            cursor: pointer;
            transition: background 0.3s;
        }

        .btn:hover {
            background: #9f8a76;
        }

        .game-container {
            position: relative;
            background: #bbada0;
            border-radius: 10px;
            padding: 10px;
            margin: 0 auto;
            width: fit-content;
        }

        .grid-container {
            position: relative;
            z-index: 1;
        }

        .grid-row {
            display: flex;
            gap: 10px;
            margin-bottom: 10px;
        }

        .grid-row:last-child {
            margin-bottom: 0;
        }

        .grid-cell {
            width: 80px;
            height: 80px;
            background: rgba(238, 228, 218, 0.35);
            border-radius: 3px;
        }

        .tile-container {
            position: absolute;
            top: 10px;
            left: 10px;
            right: 10px;
            bottom: 10px;
            z-index: 2;
        }

        .tile {
            position: absolute;
            width: 80px;
            height: 80px;
            background: #eee4da;
            border-radius: 3px;
            font-weight: bold;
            display: flex;
            justify-content: center;
            align-items: center;
            font-size: 35px;
            transition: all 0.15s ease-in-out;
            color: #776e65;
        }

        .tile-2 { background: #eee4da; color: #776e65; }
        .tile-4 { background: #ede0c8; color: #776e65; }
        .tile-8 { background: #f2b179; color: #f9f6f2; }
        .tile-16 { background: #f59563; color: #f9f6f2; }
        .tile-32 { background: #f67c5f; color: #f9f6f2; }
        .tile-64 { background: #f65e3b; color: #f9f6f2; }
        .tile-128 { background: #edcf72; color: #f9f6f2; font-size: 30px; }
        .tile-256 { background: #edcc61; color: #f9f6f2; font-size: 30px; }
        .tile-512 { background: #edc850; color: #f9f6f2; font-size: 30px; }
        .tile-1024 { background: #edc53f; color: #f9f6f2; font-size: 25px; }
        .tile-2048 { background: #edc22e; color: #f9f6f2; font-size: 25px; }

        .game-message {
            display: none;
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: rgba(238, 228, 218, 0.73);
            z-index: 100;
            text-align: center;
            border-radius: 10px;
        }

        .game-message.game-won,
        .game-message.game-over {
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
        }

        .game-message p {
            font-size: 60px;
            font-weight: bold;
            height: 60px;
            line-height: 60px;
            margin-bottom: 30px;
        }

        .game-won p {
            color: #f59563;
        }

        .game-over p {
            color: #776e65;
        }

        .restart-btn {
            display: inline-block;
            background: #8f7a66;
            border-radius: 3px;
            padding: 0 20px;
            color: #f9f6f2;
            height: 40px;
            line-height: 42px;
            cursor: pointer;
            text-decoration: none;
        }

        @media (max-width: 520px) {
            .tile {
                font-size: 25px;
            }
            
            .tile-128, .tile-256, .tile-512 {
                font-size: 20px;
            }
            
            .tile-1024, .tile-2048 {
                font-size: 15px;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>2048</h1>
            <div class="score-container">
                <div class="score-box">
                    <div class="score-label">得分</div>
                    <div class="score-value" id="score">0</div>
                </div>
                <div class="score-box">
                    <div class="score-label">最高分</div>
                    <div class="score-value" id="best-score">0</div>
                </div>
            </div>
        </div>

        <div class="controls">
            <input type="number" class="size-input" id="grid-size" placeholder="尺寸" min="4" max="10" step="2" value="4">
            <button class="btn" onclick="newGame()">新游戏</button>
        </div>

        <div class="game-container">
            <div class="grid-container" id="grid-container"></div>
            <div class="tile-container" id="tile-container"></div>
            <div class="game-message" id="game-message">
                <p></p>
                <div class="restart-btn" onclick="newGame()">再试一次</div>
            </div>
        </div>
    </div>

    <script>
        let grid = [];
        let score = 0;
        let bestScore = localStorage.getItem('bestScore') || 0;
        let size = 4;
        let hasWon = false;

        document.getElementById('best-score').textContent = bestScore;

        function initGame() {
            size = parseInt(document.getElementById('grid-size').value);
            if (size < 4 || size > 10 || size % 2 !== 0) {
                alert('请输入4-10之间的偶数尺寸！');
                document.getElementById('grid-size').value = 4;
                size = 4;
            }
            
            createGrid();
            initGrid();
            addRandomTile();
            addRandomTile();
            updateDisplay();
        }

        function createGrid() {
            const gridContainer = document.getElementById('grid-container');
            gridContainer.innerHTML = '';
            
            for (let i = 0; i < size; i++) {
                const row = document.createElement('div');
                row.className = 'grid-row';
                for (let j = 0; j < size; j++) {
                    const cell = document.createElement('div');
                    cell.className = 'grid-cell';
                    row.appendChild(cell);
                }
                gridContainer.appendChild(row);
            }

            // 调整单元格大小
            const cellSize = Math.min(80, (window.innerWidth - 100) / size);
            document.querySelectorAll('.grid-cell').forEach(cell => {
                cell.style.width = cellSize + 'px';
                cell.style.height = cellSize + 'px';
            });
            document.querySelectorAll('.tile').forEach(tile => {
                tile.style.width = cellSize + 'px';
                tile.style.height = cellSize + 'px';
            });
        }

        function initGrid() {
            grid = [];
            for (let i = 0; i < size; i++) {
                grid[i] = new Array(size).fill(0);
            }
            score = 0;
            hasWon = false;
            document.getElementById('score').textContent = score;
            document.getElementById('game-message').className = 'game-message';
        }

        function addRandomTile() {
            const emptyCells = [];
            for (let i = 0; i < size; i++) {
                for (let j = 0; j < size; j++) {
                    if (grid[i][j] === 0) {
                        emptyCells.push({x: i, y: j});
                    }
                }
            }
            
            if (emptyCells.length > 0) {
                const cell = emptyCells[Math.floor(Math.random() * emptyCells.length)];
                grid[cell.x][cell.y] = Math.random() < 0.9 ? 2 : 4;
            }
        }

        function updateDisplay() {
            const tileContainer = document.getElementById('tile-container');
            tileContainer.innerHTML = '';
            
            const cellSize = Math.min(80, (window.innerWidth - 100) / size);
            
            for (let i = 0; i < size; i++) {
                for (let j = 0; j < size; j++) {
                    if (grid[i][j] !== 0) {
                        const tile = document.createElement('div');
                        tile.className = `tile tile-${grid[i][j]}`;
                        tile.textContent = grid[i][j];
                        tile.style.left = (j * (cellSize + 10)) + 'px';
                        tile.style.top = (i * (cellSize + 10)) + 'px';
                        tile.style.width = cellSize + 'px';
                        tile.style.height = cellSize + 'px';
                        tileContainer.appendChild(tile);
                    }
                }
            }
        }

        function move(direction) {
            let moved = false;
            const newGrid = JSON.parse(JSON.stringify(grid));
            
            if (direction === 'left' || direction === 'right') {
                for (let i = 0; i < size; i++) {
                    let row = grid[i].filter(val => val !== 0);
                    if (direction === 'right') row.reverse();
                    
                    for (let j = 0; j < row.length - 1; j++) {
                        if (row[j] === row[j + 1]) {
                            row[j] *= 2;
                            score += row[j];
                            row.splice(j + 1, 1);
                        }
                    }
                    
                    while (row.length < size) {
                        row.push(0);
                    }
                    
                    if (direction === 'right') row.reverse();
                    
                    for (let j = 0; j < size; j++) {
                        if (grid[i][j] !== row[j]) moved = true;
                        grid[i][j] = row[j];
                    }
                }
            } else {
                for (let j = 0; j < size; j++) {
                    let col = [];
                    for (let i = 0; i < size; i++) {
                        col.push(grid[i][j]);
                    }
                    col = col.filter(val => val !== 0);
                    if (direction === 'down') col.reverse();
                    
                    for (let i = 0; i < col.length - 1; i++) {
                        if (col[i] === col[i + 1]) {
                            col[i] *= 2;
                            score += col[i];
                            col.splice(i + 1, 1);
                        }
                    }
                    
                    while (col.length < size) {
                        col.push(0);
                    }
                    
                    if (direction === 'down') col.reverse();
                    
                    for (let i = 0; i < size; i++) {
                        if (grid[i][j] !== col[i]) moved = true;
                        grid[i][j] = col[i];
                    }
                }
            }
            
            if (moved) {
                addRandomTile();
                updateDisplay();
                document.getElementById('score').textContent = score;
                
                if (score > bestScore) {
                    bestScore = score;
                    document.getElementById('best-score').textContent = bestScore;
                    localStorage.setItem('bestScore', bestScore);
                }
                
                if (!hasWon && grid.flat().includes(2048)) {
                    hasWon = true;
                    showMessage('You Win!', 'game-won');
                } else if (isGameOver()) {
                    showMessage('Game Over!', 'game-over');
                }
            }
        }

        function isGameOver() {
            for (let i = 0; i < size; i++) {
                for (let j = 0; j < size; j++) {
                    if (grid[i][j] === 0) return false;
                }
            }
            
            for (let i = 0; i < size; i++) {
                for (let j = 0; j < size - 1; j++) {
                    if (grid[i][j] === grid[i][j + 1]) return false;
                }
            }
            
            for (let j = 0; j < size; j++) {
                for (let i = 0; i < size - 1; i++) {
                    if (grid[i][j] === grid[i + 1][j]) return false;
                }
            }
            
            return true;
        }

        function showMessage(text, className) {
            const message = document.getElementById('game-message');
            message.querySelector('p').textContent = text;
            message.className = `game-message ${className}`;
        }

        function newGame() {
            initGame();
        }

        document.addEventListener('keydown', (e) => {
            if (document.getElementById('game-message').classList.contains('game-won') ||
                document.getElementById('game-message').classList.contains('game-over')) {
                return;
            }
            
            switch(e.key) {
                case 'ArrowLeft':
                    e.preventDefault();
                    move('left');
                    break;
                case 'ArrowRight':
                    e.preventDefault();
                    move('right');
                    break;
                case 'ArrowUp':
                    e.preventDefault();
                    move('up');
                    break;
                case 'ArrowDown':
                    e.preventDefault();
                    move('down');
                    break;
            }
        });

        // 初始化游戏
        initGame();
    </script>
</body>
</html>
